﻿//--------------------------------------------------------------------------------------------------------------------- 
// <copyright file="AddContentTypeToList.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights reserved.
// </copyright>
// <summary>
//   Defines the AddContentTypeToList type.
// </summary>
//---------------------------------------------------------------------------------------------------------------------
namespace Collaboris.Saf.Actions.Wss.ContentType
{
    using System.Collections.Generic;

    using Entities;
    using Engine;

    using SharePoint.Wss.Attributes;

    using Sharepoint.WSS.ContentTypes;
    using Utils;

    using Microsoft.SharePoint;

    [CollaborisClass(
        Title = "Add Content Type To List",
        ReleaseStatus = ReleaseStatus.Stable,
        DisableDocumentation = false,
        ContactAuthorEmail = "Support@Collaboris.co.uk",
        Summary = "Adds a specified content type to a SharePoint list. ",
        Remarks = "If the content type is <b>not</b> in the available content types list " + 
                  "it will not be added unless you specify 'ListItemUrl' in the entity.",
        ClassGuid = "{156E17A5-A7BA-4e1f-8A48-1BC341A7C639}"
    )
    ]
    public class AddContentTypeToList : WSSActionBase<ContentTypeToListMapping>
    {
        #region Methods (7)

        /// <summary>
        /// When called moves the files from the originating location
        /// to the target location.
        /// </summary>
        /// <param name="context">
        /// </param>
        /// <param name="entity">
        /// The entity.
        /// </param>
        /// <returns>
        /// </returns>
        protected override ProcessStatus DoAction(SafContext context, ContentTypeToListMapping entity)
        {

            this.Trace.TraceMethodStart("DoAction");

            ValidationHelper.VerifyObjectArgument(context.Site, "context.Site");

            if (entity.AddIfUnavailable.Value == false)
            {
                if (this.IsContentTypeAvailable(entity, TargetWeb) == false)
                {
                    this.Trace.TraceVerbose("Content is NOT availalble for the web - Not added");
                    return ProcessStatus.Warning;
                }
            }

            if (SPContentTypeHelper.AreContentTypesEnabled(TargetWeb, entity.ListName) == false &&
                entity.EnableContentTypesOnList.Value == false)
            {
                this.Trace.TraceVerbose(
                        "Content Types are NOT enabled on the List ('{0}') and "
                        + "'EnableContentTypesOnList' is set 'False'.",
                        entity.ListName);

                return ProcessStatus.Warning;
            }

            this.Trace.TraceVerbose("Adding this Content Type {0} to this list {1}", entity.ContentTypeName, entity.ListName);
            SPContentTypeHelper.AddContentTypeToList(TargetWeb, entity.ListName, entity.ContentTypeName);

            this.Trace.TraceMethodEnd("DoAction");

            return ProcessStatus.Success;
        }

        /// <summary>
        /// This has no effect.
        /// </summary>
        /// <param name="context">
        /// IContext defining the current context.
        /// </param>
        /// <param name="entity">
        /// The entity.
        /// </param>
        /// <returns>
        /// ProcessStatus.Skip
        /// </returns>
        protected override ProcessStatus UndoAction(SafContext context, ContentTypeToListMapping entity)
        {
            this.Trace.TraceMethodStart("UndoAction");

            ValidationHelper.VerifyObjectArgument(context.Site, "context.Site");

            // This may not work if it has data in the list.
            SPContentTypeHelper.RemoveContentTypeFromList(TargetWeb, entity.ListName, entity.ContentTypeName);

            this.Trace.TraceMethodEnd("UndoAction");

            return ProcessStatus.Success;
        }

        /// <summary>
        /// Checks the Data entity used by the Action for Validity
        /// </summary>
        /// <param name="context">The <see cref="SafContext"/> passed in by the SAF Engine.</param>
        /// <param name="entity">The data entity to Validate.</param>
        /// <param name="errors">List of <see cref="ValidationError"/>s</param>
        /// <param name="mode"><see cref="ProcessMode"/>signalling wheter we are Doing, or Undoing the action.</param>
        /// <returns>false if invalid; otherwise true.</returns>
        protected override bool IsValid(SafContext context, ContentTypeToListMapping entity, ref List<ValidationError> errors, ProcessMode mode)
        {
            int currentCount = errors.Count;

            // Validate each object now.
            
            ValidateStringForNull(entity.ListName, "ContentTypeToListMapping.ListName", ref errors);
            ValidateStringForNull(entity.ContentTypeName, "ContentTypeToListMapping.ContentTypeName", ref errors);

            // Have we added errors ?
            return errors.Count == currentCount;
        }

        /// <summary>
        /// Determines whether the content type is available in the Web.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="currentWeb">The current web.</param>
        /// <returns>
        /// 	<c>true</c> if it is available; otherwise, <c>false</c>.
        /// </returns>
        private bool IsContentTypeAvailable(ContentTypeToListMapping entity, SPWeb currentWeb)
        {
            this.Trace.TraceMethodStart("IsContentTypeAvailable()");
            this.Trace.TraceVerbose(
                    "Checking to see if this Ctype {0} is available in this web {1}",
                    entity.ContentTypeName,
                    entity.SiteUrl);

            if (!entity.AddIfUnavailable.HasValue)
                entity.AddIfUnavailable = false;

            if (!entity.EnableContentTypesOnList.HasValue)
                entity.EnableContentTypesOnList = false;


            this.Trace.TraceMethodEnd("IsContentTypeAvailable()");

            return SPContentTypeHelper.IsContentTypeAvailable(currentWeb, entity.ContentTypeName);
        }

        #endregion Methods
    }
}